import java.sql.*;
import java.util.Scanner;

public abstract class DBFactory {
    public abstract DBConnection CreateConnection();
    public abstract DBStatement CreateStatement();
    public abstract DBResult CreateResult();

    public static void main(String[] args){
        DBFactory factory;
        DBConnection connection;
        DBStatement statement;
        DBResult result;
        Connection conn = null;
        Statement stmt = null;
        ResultSet res = null;
        System.out.println("请输入需要连接的数据库: MySQL|SqlServer");
        Scanner sc = new Scanner(System.in);
        String db = sc.nextLine();
        try{
            factory = (DBFactory)Class.forName(db + "Factory").newInstance();
            connection = factory.CreateConnection();
            statement = factory.CreateStatement();
            result = factory.CreateResult();
            conn = connection.getConnection();
            stmt = statement.getStatement(conn);
            res = result.getResultSet(stmt,"SELECT * FROM student");
        }catch(ClassNotFoundException | InstantiationException | IllegalAccessException e){
            System.err.println("数据库输入错误");

        }finally {
            try{
                if(res != null){
                    res.close();
                }
                if(stmt != null){
                    stmt.close();
                }
                if(conn !=null) {
                    conn.close();
                }
            }catch(SQLException e){
                System.err.println("数据库错误");
            }
        }
    }
}

class MySQLFactory extends DBFactory{
    @Override
    public DBConnection CreateConnection() {
        return new MySQLConnection();
    }

    @Override
    public DBStatement CreateStatement() {
        return new MySQLStatement();
    }

    @Override
    public DBResult CreateResult() { return new MySQLResult(); }
}

class SqlServerFactory extends DBFactory{
    @Override
    public DBConnection CreateConnection() {
        return new SqlServerConnection();
    }

    @Override
    public DBStatement CreateStatement() {
        return new SqlServerStatement();
    }

    @Override
    public DBResult CreateResult() { return new SqlServerResult(); }
}

abstract class DBConnection{
    public abstract Connection getConnection();
}

abstract class DBStatement{
    public abstract Statement getStatement(Connection conn);
}

abstract class DBResult{
    public abstract ResultSet getResultSet(Statement stmt,String sql);
}

class MySQLConnection extends DBConnection{
    public static String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    public static String DB_URL = "jdbc:mysql://localhost:3306/java?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
    public static String USER = "java";
    public static String PASSWORD = "123456";

    @Override
    public Connection getConnection(){
        Connection conn = null;
        try{
            Class.forName(JDBC_DRIVER);
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL,USER,PASSWORD);
        }catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}

class MySQLStatement extends DBStatement{

    @Override
    public Statement getStatement(Connection conn) {
        Statement stmt = null;
        try{
            System.out.println("实例化Statement对象...");
            stmt = conn.createStatement();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return stmt;
    }
}

class MySQLResult extends DBResult{

    @Override
    public ResultSet getResultSet(Statement stmt,String sql) {
        ResultSet res = null;
        try{
            res = stmt.executeQuery(sql);
            while(res.next()){
                System.out.print(res.getInt("StudentID") + " ");
                System.out.print(res.getString("StudentName") + " ");
                System.out.println(res.getInt("Age"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return res;
    }
}

class SqlServerConnection extends DBConnection{
    public static String JDBC_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    public static String DB_URL = "jdbc:sqlserver://localhost:1433;DatabaseName=java";
    public static String USER = "test";
    public static String PASSWORD = "123456";

    @Override
    public Connection getConnection() {
        Connection conn = null;
        try{
            Class.forName(JDBC_DRIVER);
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}

class SqlServerStatement extends DBStatement{

    @Override
    public Statement getStatement(Connection conn){
        Statement stmt = null;
        try{
            System.out.println("实例化Statement对象...");
            stmt = conn.createStatement();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return stmt;
    }
}

class SqlServerResult extends DBResult{

    @Override
    public ResultSet getResultSet(Statement stmt, String sql) {
        ResultSet res = null;
        try{
            res = stmt.executeQuery(sql);
            while(res.next()){
                System.out.print(res.getInt("StudentID") + " ");
                System.out.print(res.getString("StudentName") + " ");
                System.out.println(res.getInt("Age"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return res;
    }
}

